// 伪NTP服务程序入口文件

/*
    说明：本文件是应用层逻辑，增加了非需求的读配置功能，核心逻辑见'./core.js'
*/

// 引入相关依赖
const { watch, readFile } = require('node:fs/promises')
const { join, isAbsolute } = require('node:path')
const { sleep } = require('./util')
const { createNTPServer } = require('./core')

//启动程序
start()

// 程序入库函数
// 增加了额外的小功能：观察服务端配置的变化自动重启服务
async function start(configPath) {
    //声明可变的服务实例变量
    let server = null
    try {
        //默认配置路径
        const thePath = configPath ?? './config.json'
        //观察配置
        const configs = wathConfig(thePath)
        //遍历configs
        for await (const config of configs) {
            console.log('server config', config)
            //关闭旧服务
            server?.stopNTPServer()
            //创建新服务实例
            server = createNTPServer(config)
            //启动服务
            server.startNTPServer()
        }
    } catch (error) {
        //捕捉异常并打印
        console.error(error)
        //关闭旧服务
        server?.stopNTPServer()
        //向开发发送邮件通知等操作,略
        //....
        //2秒后递归重启
        await sleep(2000)
        return start(configPath)
    }
}

// 观察服务端配置，返回一个异步迭代器
// 注：此处配置读取的是本地的json文件，也可以远程下载yaml等，配置的来源与格式可以多种多样
function wathConfig(configPath) {
    const thePath = isAbsolute(configPath) ? configPath : join(__dirname, configPath)
    return {
        async *[Symbol.asyncIterator]() {
            //首次读取解析
            yield parseConfig(thePath)
            //观察服务配置的变化（本地的配置文件）
            const watcher = watch(thePath)
            for await (const event of watcher) {
                // console.log(event)
                yield parseConfig(thePath)
            }
        },
    }
}

// 反序列化配置信息
async function parseConfig(configPath) {
    const data = await readFile(configPath, { encoding: 'utf8' })
    return JSON.parse(data)
}
